package au.chao.utils;

import java.io.File;
import java.io.FileWriter;
import java.io.IOException;
import java.io.PrintWriter;
import java.text.DateFormat;
import java.text.DecimalFormat;
import java.text.ParseException;
import java.util.Calendar;
import java.util.Date;

import javax.swing.JTable;

public class TenantBillReport {

	JTable tenant;
	JTable bill;
	public static final int MILLISECS_PER_DAY = (1000 * 60 * 60 * 24);
	/*
	 * determine different period tenant live in bill-time
	 */
	private final int CASE1 = 0;
	private final int CASE2 = 1;
	private final int CASE3 = 2;
	private final int CASE4 = 3;
	
	public TenantBillReport(){
		
	}
	
	public TenantBillReport(JTable t, JTable b){
		tenant = t;
		bill = b;
	}
	
	public void outputToFile(String path, String fileName) {
		PrintWriter pw = null;
		try{
			pw = new PrintWriter(new FileWriter(new File(path,fileName)));
			
			for(int i=0; i<tenant.getRowCount(); i++){
				Date t1 = DateFormat.getDateInstance().parse((String)tenant.getValueAt(i,1));
				Date t2 = null;
				if((String)tenant.getValueAt(i,2) == ""){
					t2 = Calendar.getInstance().getTime();
				}
				else{
					t2 = DateFormat.getDateInstance().parse((String)tenant.getValueAt(i,2));
				}
				String name = (String)tenant.getValueAt(i,0);
				float totalToPay = 0;
				DecimalFormat df = new DecimalFormat("###.##");
				pw.println("================================================================");
				for(int j=0; j<bill.getRowCount(); j++){
					Date b1 = DateFormat.getDateInstance().parse((String)bill.getValueAt(j,2));
					Date b2 = DateFormat.getDateInstance().parse((String)bill.getValueAt(j,3));
					float totalPrice = Float.parseFloat((String)bill.getValueAt(j,4));
					int days = getPersonalDaysOfBill(t1,t2,b1,b2);
					int totalDay = collectBillTotalDays((String)bill.getValueAt(j,0));
					
					String toPay = df.format(totalPrice * days/totalDay);
					totalToPay += totalPrice * days/totalDay;
					pw.println(name + " should pay: $" + toPay + "\tout of $" + totalPrice + 
							" for Bill:" + bill.getValueAt(j,0));
				}
				pw.println(name + " should pay: $" + df.format(totalToPay) + "\ttotally");
				
			}
			pw.close();
		}catch(ParseException e){
			e.printStackTrace();
			System.out.println("pasing date error");
		}
		catch(IOException ioe){
			ioe.printStackTrace() ;
			System.out.println("IO Error");
		}
	}
	
	private int collectBillTotalDays(String billType){
		for(int i=0; i<bill.getRowCount(); i ++){
			if(bill.getValueAt(i,0).equals(billType)){
				try{
					Date b1 = DateFormat.getDateInstance().parse((String)bill.getValueAt(i,2));
					Date b2 = DateFormat.getDateInstance().parse((String)bill.getValueAt(i,3));
					
					return getTotalDaysOfBill(b1, b2);
					
				}catch(ParseException e){
					e.printStackTrace();
					System.out.println("Date Parse Error");
				}
			}
		}
		
		return -1;
	}
	
	private int getPersonalDaysOfBill(Date t1, Date t2, Date b1, Date b2) throws ParseException{

		switch(getCase(t1,t2,b1,b2)){
			case CASE1:
				return (int)getDaysDiffence(b1, b2);
			case CASE2:
				return (int)getDaysDiffence(b1, t2);
			case CASE3:
				return (int)getDaysDiffence(t1, b2);
			case CASE4:
				return (int)getDaysDiffence(t1, t2);
			default: return -1;					
		}
	}
	
	private int getTotalDaysOfBill(Date b1, Date b2) throws ParseException{
		
		int totalDays = 0;
		for(int i=0; i< tenant.getRowCount(); i ++){
			
			Date t1 = DateFormat.getDateInstance().parse((String)tenant.getValueAt(i,1));
			Date t2 = null;
			if((String)tenant.getValueAt(i,2) == ""){
				t2 = Calendar.getInstance().getTime();
			}
			else{
				t2 = DateFormat.getDateInstance().parse((String)tenant.getValueAt(i,2));
			}
			
			switch(getCase(t1,t2,b1,b2)){
				case CASE1:
					totalDays += (int)getDaysDiffence(b1, b2);
					break;
				case CASE2:
					totalDays += (int)getDaysDiffence(b1, t2);
					break;
				case CASE3:
					totalDays += (int)getDaysDiffence(t1, b2);
					break;
				case CASE4:
					totalDays += (int)getDaysDiffence(t1, t2);
					break;
				default: return -1;					
			}
		}
		return totalDays;
	}
	
	private long getDaysDiffence(Date d1, Date d2){
		
		return ((d2.getTime() - d1.getTime()) / MILLISECS_PER_DAY );

	}
	
	private int getCase(Date t1, Date t2, Date b1, Date b2){
		
		if(t1.before(b1) && t2.after(b2)){
			return (CASE1);
		}
		if(t1.after(b1) && t2.before(b2)){
			return(CASE2);
		}
		if(t1.before(b1) && t2.after(b1) && t2.before(b2)){
			return(CASE3);
		}
		if(t1.after(b1) && t1.before(b2) && t2.after(b2)){
			return(CASE4);
		}
		return -1;
	}
	
	public static void main(String[] s){
//		getCase("11/11/2007","11/1/2007","11/11/2007","11/11/2007");
	}
	
	
	
}
